package com.rpframework.module.common.mybatis.mapper;

import com.github.pagehelper.PageInfo;
import com.rpframework.core.json.JsonResp;
import com.rpframework.core.mybatis.mapper.Paging;
import com.rpframework.module.common.bottom.entity.po.FuzzyBase;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * 通用方法
 *
 * @param <T> 实体类
 * @author 刘兴
 */
public interface BaseMapper<T> {

    class GmtDateMarry {
        public GmtDateMarry(String dateFormat, Example example) {
            this.dateFormat = dateFormat;
            this.example = example;
        }

        /**
         * 格式化数据
         */
        private String dateFormat;

        private Example example;

        public String getDateFormat() {
            return dateFormat;
        }

        public void setDateFormat(String dateFormat) {
            this.dateFormat = dateFormat;
        }

        public Example getExample() {
            return example;
        }

        public void setExample(Example example) {
            this.example = example;
        }

        public GmtDateMarry() {
        }
    }

    /**
     * 根据主键删除
     *
     * @param id 主键
     */
    JsonResp<?> deleteByIdJson(Object id);

    /**
     * {@Link}selectOne(T)
     */
    JsonResp<T> selectOneJson(T t, String emptyMsg);

    /**
     * {@Link}selectOne(T)
     */
    JsonResp<T> selectOneJson(T t);

    /**
     * {@Link}updateByPrimaryKeySelective(T)
     */
    JsonResp<Integer> updateByPrimaryKeySelectiveJson(T t);

    /**
     * 设置时间
     *
     * @param t 对象
     * @return 设置好的
     */
    T toDayBetweenSet(T t);

    /**
     * 返回实体类
     *
     * @param record 实体类
     * @param field  字段信息
     * @return 实体类
     */
    T selectByField(T record, String field);

    /**
     * 查询总数
     *
     * @param t       实体
     * @param example 条件
     * @return 条数
     */
    int selectCount(T t, Example example);

    int delete(Example e, T t);

    JsonResp deleteJson(Example e, T t);

    /**
     * 创建时间匹配
     *
     * @param date 日期
     * @return 条件
     */
    GmtDateMarry getGmtDateMarry(Date date);

    /**
     * 更新数据 无条件 空值不更新
     *
     * @param t 对象
     * @return 条数
     */
    int updateSelective(T t);

    /**
     * 更新数据 无条件 空值更新
     *
     * @param t 对象
     * @return 条数
     */
    int update(T t);

    /**
     * 插入单个JSON
     *
     * @param t 实体对象
     */
    JsonResp insertJson(T t);

    /**
     * 根据主键查询并检查主键是否存在
     * 不存在抛出异常
     *
     * @param key 主键
     * @return 实体类
     */
    T selectPrimaryKeyInspect(Object key);


    /**
     * 查询第一一条数据
     *
     * @param example 条件
     * @return 对象
     */
    T selectFirst(Example example);

    /**
     * 查询第一一条数据
     *
     * @return 对象
     */
    T selectFirst(T t);

    /**
     * @Link addOrUpdate(T)
     */
    JsonResp<?> addOrUpdateJson(T t);

    /**
     * 更新对象<br>
     * 1.不是null的更新 <br>
     * 2.字符串是 "" 不更新
     *
     * @param record  实体
     * @param example 条件
     * @return 是否更新成功
     */
    boolean updateExample(T record, Object example);

    /**
     * 更新对象<br>
     * 1.null的更新 <br>
     *
     * @param record  实体
     * @param example 条件
     * @return 是否更新成功
     */
    boolean updateExampleNullValue(T record, Object example);

    /**
     * 插入一行数据
     *
     * @param record 实体类
     * @return 是否成功
     */
    boolean insertOne(T record);

    /**
     * 添加数据 并添加成功
     *
     * @param t 实体类
     */
    void add(T t);

    /**
     * 更新数据
     *
     * @param data 数据内容NULL值不更新
     * @param e    条件 NULL=无条件
     * @return 更新条数
     */
    int update(T data, T e);

    /**
     * 查询单行数据
     *
     * @param t       实体类
     * @param example 条件对象
     * @return 一行数据
     */
    T select(T t, Object example);

    /**
     * 查询分页
     *
     * @param t      实体对象
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPage(T t, Paging paging);

    /**
     * 查询分页
     *
     * @param t      实体对象
     * @param paging 分页对象
     * @return 分页数据
     */
    JsonResp selectPageJson(T t, Paging paging);

    /**
     * 查询分页
     *
     * @param example 条件查询
     * @param paging  分页对象
     * @return 分页数据
     */
    JsonResp<PageInfo<T>> selectPageJson(Example example, Paging paging);

    /**
     * 查询分页
     *
     * @param example 条件查询
     * @param paging  分页对象
     * @return 分页数据
     */
    JsonResp<PageInfo<T>> selectPageJson(Example example, Paging paging, T t);

    PageInfo<T> selectPage(Example example, T t, Paging paging);

    /**
     * 查询分页
     *
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPage(Example example, Paging paging);

    /**
     * 查询分页
     *
     * @param paging 分页对象
     * @return 分页数据
     */
    JsonResp selectPageJSON(Example example, Paging paging);

    /**
     * 查询分页
     *
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPage(Paging paging);

    /**
     * 查询分页
     *
     * @param paging 分页对象
     * @return 分页数据
     */
    JsonResp selectPageJson(Paging paging);

    /**
     * 更新或添加 判断条件是否存在主键
     *
     * @param t 实体类
     * @return 是否更新成功
     */
    boolean addOrUpdate(T t);

    /**
     * 批量插入
     *
     * @param t 实体数据
     * @return 插入条数
     */
    JsonResp<Integer> insertListJson(List<T> t);

    /**
     * 查询分页 没有数据返回用户
     *
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPageEmpty(Paging paging, String message);

    /**
     * 查询分页 没有数据返回用户
     *
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPageEmpty(Paging paging);

    /**
     * 查询分页 没有数据返回用户
     *
     * @param t      实体对象
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPageEmpty(T t, Paging paging, String message);

    /**
     * 查询分页
     *
     * @param t      实体对象
     * @param paging 分页对象
     * @return 分页数据
     */
    PageInfo<T> selectPageEmpty(T t, Paging paging);

    /**
     * 批量删除主键
     *
     * @param ids 主键
     * @return 是否完全删除
     */
    boolean deleteIds(Object[] ids);

    /**
     * 批量删除主键
     *
     * @param ids 主键
     */
    JsonResp<?> deleteIdsJson(Object[] ids);

    /**
     * 批量删除主键
     *
     * @param ids 主键
     */
    JsonResp<?> deleteIdsJson(List<Object> ids);

    /**
     * 批量删除主键
     *
     * @param ids 主键
     * @return 是否完全删除
     */
    void deleteIdsAll(Object[] ids);

    /**
     * 批量删除主键
     *
     * @param ids 主键
     * @return 是否完全删除
     */
    boolean deleteIds(List<Object> ids);

    /**
     * 条件删除
     */
    JsonResp deleteJson(T t);

    /**
     * 批量删除主键
     *
     * @param ids 主键
     * @return 是否完全删除
     */
    void deleteIdsAll(List<Object> ids);

    /**
     * 查询一个对象如果不存在抛出异常
     *
     * @param id      主键
     * @param message 消息
     * @return JSON对象
     */
    JsonResp selectById(Object id, String message);

    /**
     * 查询一个对象如果不存在抛出异常
     *
     * @param id 主键
     * @return JSON对象
     */
    JsonResp selectById(Object id);

    /**
     * 查询所有
     *
     * @param message 消息
     * @return JSON对象
     */
    JsonResp selectJson(String message);

    /**
     * 查询所有
     *
     * @return JSON对象
     */
    JsonResp selectJson();

    /**
     * 模糊查找
     *
     * @param t             数据
     * @param isEmpty       isEmpty
     * @param excludeFields 排除字段
     * @return class
     */
    List<T> fuzzySearch(T t, boolean isEmpty, String... excludeFields);

    /**
     * 模糊查找
     *
     * @param t 数据
     * @return class
     */
    PageInfo<T> fuzzySearch(T t, Paging paging);

    /**
     * 模糊查找
     *
     * @param t 数据
     * @return class
     */
    JsonResp<PageInfo<T>> fuzzySearchJson(T t, Paging paging);


    /**
     * 模糊查找 不排除字段
     *
     * @param t       数据
     * @param isEmpty isEmpty
     * @return class
     */
    List<T> fuzzySearch(T t, boolean isEmpty);

    /**
     * 模糊查找，不排除字段
     *
     * @param t 数据
     * @return class
     */
    List<T> fuzzySearch(T t);

    /**
     * 模糊查找
     *
     * @param t             数据
     * @param isEmpty       isEmpty
     * @param excludeFields 排除字段
     * @return class
     */
    List<T> fuzzySearch(T t, boolean isEmpty, Example example, String... excludeFields);

    /**
     * 模糊查找排除空字符串
     *
     * @param t             数据
     * @param excludeFields 排除字段
     * @return class
     */
    List<T> fuzzySearchEmpty(T t, String... excludeFields);

    /**
     * 模糊查找排除空字符串
     *
     * @param t             数据
     * @param excludeFields 排除字段
     * @return class
     */
    List<T> fuzzySearchEmpty(T t, Example example, String... excludeFields);

    /**
     * 模糊查找 排除主键
     *
     * @param t 数据
     * @return class
     */
    List<T> fuzzySearchExcludePrimaryKey(T t);

    /**
     * 模糊查找 排除主键
     *
     * @param t       数据
     * @param example 条件
     * @return class
     */
    List<T> fuzzySearchExcludePrimaryKey(T t, Example example);

    /**
     * 模糊查找
     *
     * @param t             数据
     * @param isEmpty       isEmpty
     * @param excludeFields 排除字段
     * @return class
     */
    PageInfo<T> fuzzySearch(T t, boolean isEmpty, Paging paging, String... excludeFields);

    /**
     * 模糊查找
     *
     * @param t             数据
     * @param isEmpty       isEmpty
     * @param excludeFields 排除字段
     * @return class
     */
    PageInfo<T> fuzzySearch(T t, boolean isEmpty, Paging paging, Example example, String... excludeFields);

    /**
     * 模糊查找
     *
     * @param t             数据
     * @param fuzzy         不模糊匹配字段
     * @param isEmpty       isEmpty
     * @param excludeFields 排除字段
     * @return class
     */
    PageInfo<T> fuzzySearch(T t, boolean isEmpty, Paging paging, Example example, T fuzzy, String... excludeFields);

    /**
     * 模糊查找
     *
     * @param t             数据
     * @param fuzzy         不模糊匹配字段
     * @param isEmpty       isEmpty
     * @param excludeFields 排除字段
     * @return class
     */
    List<T> fuzzySearch(T t, boolean isEmpty, Example example, T fuzzy, String... excludeFields);

    List<T> fuzzySearch(T t, Example example, T fuzzy, String... excludeFields);

    PageInfo<T> fuzzySearch(T t, Example example, T fuzzy, Paging p);

    List<T> fuzzySearch(T t, T fuzzy, String... excludeFields);


    List<T> fuzzySearch(T t, T fuzzy);

    JsonResp<List<T>> fuzzySearchJson(T t, T fuzzy);

    /**
     * 模糊查找排除空字符串
     *
     * @param t             数据
     * @param excludeFields 排除字段
     * @return class
     */
    PageInfo<T> fuzzySearchEmpty(T t, Paging paging, String... excludeFields);

    /**
     * 模糊查找排除空字符串
     *
     * @param t             数据
     * @param excludeFields 排除字段
     * @return class
     */
    PageInfo<T> fuzzySearchEmpty(T t, Paging paging, Example example, String... excludeFields);

    /**
     * 模糊查找 排除主键
     *
     * @param t      数据
     * @param paging 分页
     * @return class
     */
    PageInfo<T> fuzzySearchExcludePrimaryKey(T t, Paging paging);

    /**
     * 模糊查找 排除主键
     *
     * @param t       数据
     * @param paging  分页
     * @param example 条件
     * @return class
     */
    PageInfo<T> fuzzySearchExcludePrimaryKey(T t, Paging paging, Example example);

    /**
     * 查询所有记录JSON对象返回
     *
     * @return JSON对象
     */
    JsonResp<List<T>> selectAllJson();

    /**
     * 分页
     *
     * @param paging 页码/数量初始化
     */
    void startPage(Paging paging);

    /**
     * 批量修改
     *
     * @param ts 对象
     * @return 更新条数
     */
    int updates(List<T> ts);

    /**
     * 批量修改
     *
     * @param ts 对象
     * @return 更新条数
     */
    boolean updatesAll(List<T> ts);

    /**
     * 批量修改 JSON返回
     *
     * @param ts 对象
     * @return JSON
     */
    JsonResp updatesJson(List<T> ts);

    /**
     * 查询多个根据主键
     *
     * @param ids 主键
     * @return 集合
     */
    List<T> selectsByIds(Object[] ids);

    /**
     * 查询多个根据主键
     *
     * @param ids 主键
     * @return 集合
     */
    List<T> selectsByIds(List<? extends Object> ids);

    /**
     * 查询多个根据主键
     *
     * @param ids 主键
     * @return 集合
     */
    JsonResp<List<T>> selectsByIdsJson(Object[] ids);

    /**
     * 查询集合
     *
     * @param t       对象
     * @param example 条件
     * @return 集合
     */
    List<T> selects(T t, Example example);

    /**
     * 查询集合返回JSON
     *
     * @param t       对象
     * @param example 条件
     * @return JSON
     */
    JsonResp<List<T>> selectsJson(T t, Example example);

    /**
     * 查询集合返回JSON
     *
     * @param t 对象
     * @return JSON
     */
    JsonResp<List<T>> selectsJson(T t);

    /**
     * 查询集合 分页
     *
     * @param paging  分页对象
     * @param t       对象
     * @param example 条件
     * @return 分页数据
     */
    PageInfo<T> selects(Paging paging, T t, Example example);

    /**
     * 查询集合 分页 JSON
     *
     * @param paging  分页对象
     * @param t       对象
     * @param example 条件
     * @return 分页数据 JSON
     */
    JsonResp selectsJson(Paging paging, T t, Example example);

    /**
     * 对象加条件
     *
     * @param t       实体对象
     * @param example 条件
     * @return 集合
     */
    List<T> fuzzySearch(T t, Example example);


    JsonResp fuzzySearchJson(T t, Example example);

    JsonResp fuzzySearchJson(T t);


    PageInfo<T> fuzzyBaseField(T t, FuzzyBase fuzzyBase, Paging paging);


    JsonResp<PageInfo<T>> fuzzyBaseFieldJson(T t, FuzzyBase fuzzyBase, Paging paging);


    JsonResp fuzzyBaseFieldJson(T t, FuzzyBase fuzzyBase);


    PageInfo<T> selectBaseField(T t, FuzzyBase fuzzyBase, Paging paging);


    List<T> selectBaseField(T t, FuzzyBase fuzzyBase);

    /**
     * 包括没有不模糊匹配字段
     *
     * @param t         模糊匹配
     * @param n         不模糊匹配
     * @param fuzzyBase 时间段条件
     * @return 列表
     */
    List<T> selectBaseField(T t, T n, FuzzyBase fuzzyBase);

    PageInfo<T> selectBaseFieldPage(T t, T n, FuzzyBase fuzzyBase, Paging paging);


    JsonResp<PageInfo<T>> selectBaseFieldJson(T t, FuzzyBase fuzzyBase, Paging paging);


    JsonResp<List<T>> selectBaseFieldJson(T t, FuzzyBase fuzzyBase);


    List<T> fuzzyBaseField(T t, FuzzyBase fuzzyBase);

    /**
     * 获取条件对象
     *
     * @param example 条件
     * @return 如果example不存在NEW，如果Criteria不存在NEW
     */
    Example.Criteria getExampleCriteria(Example example);

    /**
     * 条件对象初始化
     *
     * @param example 条件
     * @return 不存在NEW
     */
    Example init(Example example);


    Example.Criteria getExampleCriteria();
}
